<script>
import aimAttrs from "./components/aimAttrs.vue";
import myComponent from "./components/myComponent.vue";
import key from "keymaster";

import { h, toRefs, defineComponent, reactive, getCurrentInstance } from "vue";
import { useStore } from "vuex";

const fs = window.require("fs");

export default defineComponent({
  name: "App",
  components: {
    myComponent,
    aimAttrs,
  },
  setup() {
    const $store = useStore();
    const proxy = getCurrentInstance().appContext.config.globalProperties;

    let data = reactive({
      tree: $store.state.page.tree, // 编辑区数据树
      showAttrsList: false, // 属性
      showcomponetList: true, // 组件
      colBoxDialog: false, // 多列布局
      colBoxDialogRadio: "1", // 多列布局数量
      colBoxWidth: [48, 48], // 多列布局宽度
      pageName: "index", // 页面名称
      pageDialog: false, // 页面布局
      newPageName: "", // 新页面名称
      seniorBoxDialog: false, // 高级布局
      imgList: [], // 保存页面所用图片的blob地址和本地地址
    });

    // 清理多余图片
    const delete_uselessImage = () => {
      let list = [];
      let filesList;

      // 清洗数据
      for (const key in data.imgList) {
        if (Object.hasOwnProperty.call(data.imgList, key)) {
          list.push(data.imgList[key].src);
        }
      }

      try {
        // 获取文件夹下面的全部图片路径
        filesList = fs.readdirSync(proxy.__filePath + "/developPageImage");
        // 删除多余图片
        filesList.forEach((item) => {
          let imgPath = proxy.__filePath + "/developPageImage/" + item;
          // 如果页面图片引用列表中没有--则删除
          if (!list.includes(imgPath)) {
            fs.unlinkSync(imgPath);
          }
        });
      } catch (error) {
        console.error(error);
      }
    };
    // 控制组件列表显示/隐藏
    const change_showcomponetList = () => {
      data.showcomponetList = !data.showcomponetList;
      // 如果这时候属性列表显示，则隐藏它
      data.showAttrsList && (data.showAttrsList = false);
    };
    // 控制属性列表显示/隐藏
    const change_showAttrsList = () => {
      data.showAttrsList = !data.showAttrsList;
      // 如果这时候组件列表显示，则隐藏它
      data.showcomponetList && (data.showcomponetList = false);
    };
    // 撤销操作
    const cancel_deedStack = () => {
      // 判断存储栈为不为空
      if ($store.state.domStackNum == -1) return;
      $store.commit("deedStackChange", {
        that: proxy,
        type: "cancel",
      });
    };
    // 恢复操作
    const restore_deedStack = () => {
      // 判断存储栈控制下标是否在栈顶--即已经没有东西可以恢复了
      if ($store.state.domStackNum == $store.state.domStack.length - 1) return;
      $store.commit("deedStackChange", {
        that: proxy,
        type: "restore",
      });
    };
    return {
      proxy,
      ...toRefs(data),
      delete_uselessImage,
      change_showcomponetList,
      change_showAttrsList,
      cancel_deedStack,
      restore_deedStack,
    };
  },
  created() {
    // 加载页面数据
    this.$store.commit("loadPageData", { that: this.proxy });

    // 快捷键绑定
    // 控制组件列表显示/隐藏
    key("shift + q", this.change_showcomponetList);
    // 控制属性列表显示/隐藏
    key("shift + w", this.change_showAttrsList);
    // 显示页面布局
    key("shift + e", () => {
      this.pageDialog = !this.pageDialog;
    });
    // 打包
    key("shift + a", () => {
      this.$store.commit("packPage", {
        treeData: JSON.stringify(this.tree),
        that: this.proxy,
      });
    });
    // 保存
    key("shift + s", () => {
      this.$store.commit("storeData", { that: this.proxy });
    });
    // 进入捕捉模式
    key("shift + d", () => {
      this.showAttrsList = false;
      this.showcomponetList = false;
      this.$store.commit("changeJudgeColorDom", { that: this.proxy });
    });
    // 撤销操作
    key("shift + z", this.cancel_deedStack);
    // 恢复操作
    key("shift + y", this.restore_deedStack);
  },
  beforeDestroy() {
    this.delete_uselessImage();
  },
  render() {
    let that = {
      ...this.proxy,
      pageName: this.pageName,
      colBoxWidth: this.colBoxWidth,
    };
    return (
      <div>
        {/*菜单 */}
        <div class="menu">
          <a-button size="large" onClick={this.change_showcomponetList}>
            <AppstoreOutlined /> 组件
          </a-button>
          <a-button size="large" onClick={this.change_showAttrsList}>
            <ToolOutlined /> 样式
          </a-button>
          <a-button
            size="large"
            onClick={() => {
              this.pageDialog = true;
            }}
          >
            <ClusterOutlined /> 结构
          </a-button>
          <a-button
            size="large"
            onClick={() => {
              this.$store.commit("packPage", {
                treeData: JSON.stringify(this.tree),
                that,
              });
            }}
          >
            <SettingOutlined /> 打包
          </a-button>
          <a-button
            size="large"
            onClick={() => {
              this.$store.commit("storeData", { that });
            }}
          >
            <InboxOutlined /> 保存
          </a-button>
          <a-button
            size="large"
            disabled={this.$store.state.domStackNum == -1}
            onClick={this.cancel_deedStack}
          >
            <RollbackOutlined /> 撤销
          </a-button>
          <a-button
            size="large"
            disabled={
              this.$store.state.domStackNum ==
              this.$store.state.domStack.length - 1
            }
            onClick={this.restore_deedStack}
          >
            <RetweetOutlined /> 恢复
          </a-button>
        </div>

        {/*组件 */}
        <myComponent class="float component" v-show={this.showcomponetList} />

        {/*网页编辑区*/}
        <div
          class="app produce"
          onDragover={(e) => {
            e.preventDefault();
          }}
          onDragenter={(e) => {
            this.$store.commit("store_dragenter", { e, that });
          }}
          onDragleave={(e) => {
            this.$store.commit("store_dragleave", { e, that });
          }}
          onDrop={(e) => {
            this.$store.commit("store_ondrop", { e, that });
            this.$store.commit("store_dragleave", { e, that });
          }}
          onDragstart={(e) => {
            this.$store.commit("store_ondragstart", { e, that });
          }}
          onMouseover={(e) => {
            if (this.$store.state.judgeColorDom) {
              this.$store.commit("mouseoverColorChange", { e, that });
            }
            e.stopImmediatePropagation();
          }}
          onClick={(e) => {
            if (this.$store.state.judgeColorDom) {
              this.$store.commit("checkDomAttrs", { e, that });
              this.$store.commit("changeJudgeColorDom", { e, that });
              this.change_showAttrsList();
            }
            e.stopImmediatePropagation();
          }}
          style={{
            width: "1224px",
            margin: "0 auto",
            border: "1px solid #ccc",
          }}
          data-type="app"
        >
          {this.tree[this.pageName].length != 0
            ? this.$explain(this, h, this.tree[this.pageName])
            : null}
        </div>

        {/*样式 */}
        <aimAttrs
          v-show={this.showAttrsList}
          onChangeShowAttrsList={(jud) => (this.showAttrsList = jud)}
          class="float"
          that={that}
        />

        {/*遮蔽层 */}
        {this.$store.state.judgeColorDom &&
          this.$store.state.colorDomStyle.top && (
            <div
              class="colorDom"
              style={{
                top: this.$store.state.colorDomStyle.top,
                left: this.$store.state.colorDomStyle.left,
                borderWidth: this.$store.state.colorDomStyle.margin,
              }}
            >
              <div
                style={{
                  margin: this.$store.state.colorDomStyle.border,
                  borderWidth: this.$store.state.colorDomStyle.padding,
                  width: this.$store.state.colorDomStyle.width,
                  height: this.$store.state.colorDomStyle.height,
                }}
              ></div>
            </div>
          )}

        {/* 多列容器选择 */}
        <a-modal
          visible={this.colBoxDialog}
          cancelText="取消"
          okText="确定"
          onCancel={(e) => {
            this.colBoxDialog = false;
          }}
          onOk={() => {
            this.$store.commit("controlColBoxDialog", { that });
            this.colBoxDialog = false;
          }}
        >
          <span>
            <a-radio-group
              value={this.colBoxDialogRadio}
              onChange={(e) => {
                this.colBoxDialogRadio = e.target.value;
                if (e == "1") {
                  this.colBoxWidth = [48, 48];
                } else {
                  this.colBoxWidth = [32, 32, 32];
                }
              }}
              style={{ width: "100%", textAlign: "center" }}
            >
              <a-radio-button value="1">两列</a-radio-button>
              <a-radio-button value="2">三列</a-radio-button>
            </a-radio-group>
            <div class="colBoxWidth">
              <div>
                <span>第一列宽度</span>
                <a-input-number
                  value={this.colBoxWidth[0]}
                  onChange={(e) => {
                    this.colBoxWidth[0] = e;
                  }}
                  min={10}
                  max={
                    this.colBoxDialogRadio == "2"
                      ? 96 - this.colBoxWidth[1] - this.colBoxWidth[2]
                      : 96 - this.colBoxWidth[1]
                  }
                ></a-input-number>
              </div>
              <div>
                <span>第二列宽度</span>
                <a-input-number
                  value={this.colBoxWidth[1]}
                  min={10}
                  max={
                    this.colBoxDialogRadio == "2"
                      ? 96 - this.colBoxWidth[0] - this.colBoxWidth[2]
                      : 96 - this.colBoxWidth[0]
                  }
                  onChange={(e) => {
                    this.colBoxWidth[1] = e;
                  }}
                ></a-input-number>
              </div>
              {this.colBoxDialogRadio == "2" && (
                <div>
                  <span>第三列宽度</span>
                  <a-input-number
                    value={this.colBoxWidth[2]}
                    min={10}
                    max={96 - this.colBoxWidth[1] - this.colBoxWidth[0]}
                    onChange={(e) => {
                      this.colBoxWidth[2] = e;
                    }}
                  ></a-input-number>
                </div>
              )}
            </div>
          </span>
        </a-modal>

        {/* 高级容器选择 */}
        <a-modal
          visible={this.seniorBoxDialog}
          title="请选择布局"
          onOk={() => {
            this.seniorBoxDialog = false;
          }}
          onCancel={() => {
            this.seniorBoxDialog = false;
          }}
        >
          <div
            class="seniorBoxList"
            onClick={(e) => {
              this.$store.commit("controlSeniorBoxDialog", { e, that });
              this.seniorBoxDialog = false;
            }}
          >
            {this.$store.state.seniorBoxList.map((element, ind) => {
              return (
                <div class={ind.toString()}>
                  {this.$explain(this, h, element)}
                </div>
              );
            })}
          </div>
        </a-modal>

        {/* 网站结构 */}
        <a-modal
          visible={this.pageDialog}
          class="webPage"
          title="下列为已有页面"
          cancelText="关闭"
          okText="确定"
          onCancel={() => {
            this.pageDialog = false;
          }}
          onOk={() => {
            this.pageDialog = false;
          }}
        >
          <div class="webPageList">
            {Object.keys(this.tree)
              .reverse()
              .map((key) => {
                return (
                  <div style={{ textAlign: "center", margin: "10px" }}>
                    <p>{key}</p>
                    <img
                      src={require("./assets/images/page.png")}
                      width="110"
                      height="90"
                    />
                    <div
                      style={{
                        display: "flex",
                        "justify-content": "space-between",
                        marginTop: "10px",
                      }}
                    >
                      {key == this.pageName ? null : (
                        <a-button
                          type="primary"
                          ghost
                          onClick={() => {
                            if (this.pageName != key) this.pageName = key;
                            this.pageDialog = false;
                          }}
                        >
                          查看
                        </a-button>
                      )}
                      {key == "index" ? null : (
                        <a-popconfirm
                          title="确定删除组件？"
                          onConfirm={() => {
                            this.$store.commit("deletePage", {
                              that,
                              deletePageName: key,
                            });
                          }}
                        >
                          <a-button danger>删除</a-button>
                        </a-popconfirm>
                      )}
                    </div>
                  </div>
                );
              })}
          </div>
          <div class="dialog-footer">
            <a-input
              v-model={[this.newPageName, "value"]}
              placeholder="请输入新页面名称"
            ></a-input>
            <a-button
              type="primary"
              onClick={() => {
                this.$store.commit("createPage", {
                  that,
                });
              }}
            >
              新 建
            </a-button>
          </div>
        </a-modal>
      </div>
    );
  },
});
</script>

<style lang="less">
* {
  // outline: 1px red solid !important;
}

//用户开发环境样式
.produce {
  margin-bottom: 5px;
  div[data-type="fixedBox"]:hover,
  div[data-type="freeBox"]:hover,
  div[data-type="colBoxItem"]:hover,
  div[data-type="seniorBoxItem"]:hover {
    outline: 1.5px #0084ff dashed !important;
  }
}

//更改的样式
.app {
}

//菜单
.menu {
  position: fixed;
  z-index: 999;
  width: 70px;
  top: 40%;
  transform: translateY(-50%);
  > button {
    margin: 5px;
  }
  .ant-btn {
    font-size: 16px;
    font-weight: 600;
    color: rgb(64, 158, 255);
    border-color: rgb(64, 158, 255);
    background: rgb(255, 255, 255);
  }
  .ant-btn:hover {
    color: rgb(255, 255, 255);
    background: rgb(64, 158, 255);
  }
}

//
.float {
  position: fixed;
  top: 5vh;
  right: 0;
  border: #ccc 1px solid;
  min-height: 20vh;
  max-height: 80vh;
  overflow: auto;
  z-index: 99;
  background-color: #fff;
  min-width: 350px;
}

.component {
  background-color: #fff;
  .componentList {
    display: flex;
    justify-content: space-between;
    .box {
      width: 80px;
      margin: 8px;
      text-align: center;
      color: #555;
      font-size: 15px;
    }
  }
}

//组件样式
.text {
  text-align: center;
}

//遮蔽层
.colorDom {
  position: absolute;
  z-index: 999;
  opacity: 0.35;
  pointer-events: none;
  background: rgb(255, 251, 0);
  border-color: orange;
  border-style: solid;
  > div {
    border-style: solid;
    border-color: rgb(21, 255, 0);
    background: repeating-linear-gradient(
      30deg,
      #0084ff,
      #0084ff 10px,
      #2093ff 0,
      #2093ff 20px
    );
  }
}

// .redLine {
//   outline: 1px red solid !important;
//   background: repeating-linear-gradient(
//     30deg,
//     #8c00ff3a,
//     #8c00ff3a 10px,
//     #6800bd41 0,
//     #6800bd41 20px
//   ) !important;
// }

.boxLine {
  outline: 2px #0084ff dashed !important;
}

.webPage {
  .webPageList {
    display: flex;
    overflow-y: auto;
    width: 100%;
    flex-wrap: wrap;
    height: 40vh;
    justify-content: space-around;
  }
  .dialog-footer {
    display: flex;
  }
}

.colBoxWidth {
  margin: 10px;
  > div {
    margin: 10px;
    display: flex;
    justify-content: space-around;
  }
}

.seniorBoxList {
  display: flex;
  flex-wrap: wrap;
  > div {
    margin: 5px;
    width: 110px;
    height: 74px;
    display: flex;
    justify-content: space-around;
  }
  > div:hover {
    outline: 2px dotted #0084ff;
    background: #0084ff75;
  }
  div {
    border-radius: 5px;
  }
  .seniorBoxItem0 {
    background-color: #3ec1d3;
  }
  .seniorBoxItem1 {
    background-color: #ff9a00;
  }
  .seniorBoxItem2 {
    background-color: #ff165d;
  }
  .seniorBoxItem3 {
    background-color: #94da12;
  }
  .seniorBoxItem4 {
    background-color: #0070d8;
  }
}
</style>
